home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / mus / play / tracker_4_31.lzh / tracker / Amiga / audio.c < prev    next >
C/C++ Source or Header  |  1995-05-11  |  9KB  |  420 lines

  1. /* amiga/audio.c 
  2.     vi:ts=3 sw=3:
  3.  */
  4. /* $Id: audio.c,v 1.12 1995/05/11 12:09:07 espie Exp espie $
  5.  * $Log: audio.c,v $
  6.  * Revision 1.12  1995/05/11  12:09:07  espie
  7.  * Dummy call added.
  8.  *
  9.  * Revision 1.11  1995/02/14  16:51:22  espie
  10.  * *** empty log message ***
  11.  *
  12.  * Revision 1.10  1995/02/13  22:05:42  espie
  13.  * Implemented new allocation policy.
  14.  * Updated calls to refer to new release.
  15.  *
  16.  * Revision 1.9  1995/01/13  13:31:35  espie
  17.  * *** empty log message ***
  18.  *
  19.  *
  20.  * Revision 1.6  1994/01/08  04:00:52  Espie
  21.  * added obtain_sample, renamed release_audio_channel,
  22.  * new_channel_tag_list.
  23.  * Major change: moved timing computations to the audio server.
  24.  * Pause is now feasible !
  25.  * Better automatic time adjustement.
  26.  * Ability to play long samples.
  27.  * Modified task pseudoinit in case
  28.  * we use an external server.
  29.  * Removed some typecasts.
  30.  * Added SYNC_DO hook facility.
  31.  * FLUSH_BUFFER on end_all.
  32.  * Messages now initialized correctly
  33.  * Added external sound server for debug.
  34.  */
  35.  
  36. #include <proto/exec.h>
  37. #include <proto/timer.h>
  38.  
  39. #include <exec/types.h>
  40. #include <exec/memory.h>
  41. #include <exec/ports.h>
  42.  
  43. #include "defs.h"
  44. #include "extern.h"
  45. #include "song.h"
  46. #include "tags.h"
  47. #include "amiga/amiga.h"
  48.  
  49. ID("$Id: audio.c,v 1.12 1995/05/11 12:09:07 espie Exp espie $")
  50.  
  51. #define AMIGA_MAX_SAMPLE_LENGTH  131072
  52. #define AMIGA_MIN_SAMPLE_LENGTH  2
  53.  
  54. LOCAL void init_audio(void);
  55. LOCAL void (*INIT)(void) = init_audio;
  56.  
  57. XT unsigned int inhibit_output;
  58.  
  59. LOCAL struct Library *TimerBase = 0;
  60. LOCAL struct timerequest *tr = 0;
  61.  
  62. /* remember allocated samples for cleaning up in panic case */
  63. LOCAL struct MinList tracked_list;
  64.  
  65.  
  66. LOCAL void free_things()
  67.    {
  68.    struct MinNode *current, *next;
  69.  
  70.    SCANLIST(current, next, &tracked_list, struct MinNode *)
  71.       FreeVec(current);
  72.    if (TimerBase)
  73.       CloseDevice(tr);
  74.    if (tr)
  75.       FreeVec(tr);
  76.    }
  77.       
  78.  
  79. /* kludge alert: we allocate arbitrary channel numbers around here.
  80.  * This is probably temporary, and definitely NOT the way to go !
  81.  */
  82.  
  83. LOCAL struct audio_channel
  84.    {
  85.    int amiga_number;
  86.    struct sample_info *samp;
  87.    int volume;
  88.    int pitch;
  89.    } chan[4];
  90.  
  91. LOCAL int allocated = 0;
  92. LOCAL int left_allocated = 0;
  93. LOCAL int right_allocated = 0;
  94.  
  95. LOCAL int free_channel[2][3] =
  96.    {
  97.       {0,3,-1},
  98.       {1,2,-1}
  99.    };
  100.  
  101. struct audio_channel *new_channel_tag_list(struct tag *prop)
  102.    {
  103.    struct audio_channel *new;
  104.  
  105.    INIT_ONCE;
  106.  
  107.    new = &chan[allocated];
  108.    while (prop = get_tag(prop))
  109.       {
  110.       switch(prop->type)
  111.          {
  112.       case AUDIO_SIDE:
  113.          switch(prop->data.scalar)
  114.             {
  115.          case LEFT_SIDE:
  116.             new->amiga_number = free_channel[LEFT_SIDE][left_allocated];
  117.             if (new->amiga_number != -1)
  118.                left_allocated++;
  119.             else
  120.                return NULL;
  121.             break;
  122.          case RIGHT_SIDE:
  123.             new->amiga_number = free_channel[RIGHT_SIDE][right_allocated];
  124.             if (new->amiga_number != -1)
  125.                right_allocated++;
  126.             else
  127.                return NULL;
  128.             break;
  129.          default:
  130.             return NULL;
  131.             }
  132.          break;
  133.       default:
  134.          }
  135.       prop++;
  136.       }
  137.          
  138.    allocated++;
  139.    new->samp = empty_sample();
  140.    new->volume = 0;
  141.    new->pitch = 0;
  142.    new->samp = 0;
  143.    return new;
  144.    }
  145.  
  146. void release_audio_channels()
  147.    {
  148.    left_allocated = right_allocated = allocated = 0;
  149.    }
  150.  
  151.  
  152. /* Special sample management on the amiga */
  153. void *alloc_sample(int len)
  154.    {
  155.    char *s;
  156.  
  157.    INIT_ONCE
  158.    
  159.    s = AllocVec(len + sizeof(struct MinNode), MEMF_CHIP | MEMF_CLEAR);
  160.    if (!s)
  161.       return 0;
  162.    AddTail(&tracked_list, (struct Node *)s);
  163.    return s + sizeof(struct MinNode);
  164.    }
  165.  
  166.  
  167. /* note we have to synchronize audio output before we free the sample */
  168. #define sync_audio close_audio
  169.  
  170. void free_sample(char *s)
  171.    {
  172.    sync_audio();
  173.    s -= sizeof(struct MinNode);
  174.    Remove((struct Node *)s);
  175.    FreeVec(s);
  176.    }
  177.  
  178. int obtain_sample(char *start, int l, struct exfile *f)
  179.    {
  180.    return read_file(start, 1, l, f);
  181.    }
  182.  
  183.  
  184. LOCAL void init_timer()
  185.    {
  186.    int error;
  187.  
  188.    tr = AllocVec(sizeof(struct timerequest), MEMF_PUBLIC | MEMF_CLEAR);
  189.    if (!tr)
  190.       end_all("No timerequest");
  191.    error = OpenDevice(TIMERNAME, UNIT_MICROHZ, tr, 0);
  192.    if (error)
  193.       end_all("Could not open timer");
  194.    TimerBase = (struct Library *)tr->tr_node.io_Device;
  195.    }
  196.  
  197.  
  198. LOCAL void init_audio()
  199.    {
  200.    NewList(&tracked_list);
  201.    at_end(free_things);
  202.    init_timer();
  203.    }
  204.  
  205. /* indispensible for not losing memory ! */
  206.  
  207. void __regargs __chkabort()
  208.    {
  209.    }
  210.    
  211. /* audio */
  212.  
  213. /* empty operation on the amiga */
  214. void init_tables(oversample, frequency)
  215. int oversample, frequency;
  216.    {
  217.    }
  218.  
  219. void set_data_width(n, p)
  220. int n, p;
  221.    {
  222.    }
  223.  
  224. void resample(oversample, number)
  225. int oversample;
  226. int number;
  227.    {
  228.    struct ext_message *msg;   
  229.  
  230.    INIT_ONCE;
  231.    msg = obtain_message();
  232.    msg->data.time.low = (unsigned long)number;
  233.    msg->data.time.high = 0;
  234.    send(msg, TYPE_WAIT);
  235.    }
  236.  
  237.  
  238. /* So you can play long samples with short repeat parts */
  239. LOCAL void play_long_sample(struct audio_channel *au, UBYTE *start, int length)
  240.    {
  241.    struct ext_message *msg, *msg2;
  242.    int chunk;
  243.    while (length >= AMIGA_MIN_SAMPLE_LENGTH)
  244.       {
  245.       chunk = MIN(AMIGA_MAX_SAMPLE_LENGTH, length);
  246.       msg = obtain_message();
  247.       msg2 = obtain_message();
  248.       msg->data.sample.start = start;
  249.       msg->data.sample.length = chunk;
  250.       msg2->data.info.channel_mask = 1<<au->amiga_number;
  251.       msg2->data.info.cycle = 1;
  252.       msg2->data.info.pitch = au->pitch;
  253.       msg2->data.info.volume = au->volume;
  254.       Forbid();
  255.       send(msg, TYPE_SETUP);
  256.       send(msg2, TYPE_CHANGE);
  257.       Permit();
  258.       length -= chunk;
  259.       start += chunk;
  260.       }
  261.    }
  262.  
  263. void play_note(au, samp, pitch)
  264. struct audio_channel *au;
  265. struct sample_info *samp;
  266. int pitch;
  267.    {
  268.    struct ext_message *msg, *msg2;
  269.  
  270.    au->pitch = pitch;
  271.    msg = obtain_message();
  272.    msg->data.info.channel_mask = 1<<au->amiga_number;
  273.    send(msg, TYPE_FLUSH_CHANNEL);
  274.    
  275.    if (samp)
  276.       {
  277.       au->samp = samp;
  278.       if (samp->start)
  279.          {
  280.          play_long_sample(au, samp->start, samp->length);
  281.          if (samp->rp_start)
  282.             {
  283.             msg = obtain_message();
  284.             msg2 = obtain_message();
  285.             msg->data.sample.start = samp->rp_start;
  286.             msg->data.sample.length = samp->rp_length;
  287.             msg2->data.info.channel_mask = 1<<au->amiga_number;
  288.             msg2->data.info.cycle = 0;
  289.             msg2->data.info.pitch = 0;
  290.             msg2->data.info.volume = 0;
  291.             Forbid();
  292.             send(msg, TYPE_SETUP);
  293.             send(msg2, TYPE_CHANGE);
  294.             Permit();
  295.             }  
  296.          }
  297.       }
  298.    }
  299.  
  300. void set_play_pitch(au, pitch)
  301. struct audio_channel *au;
  302. int pitch;
  303.    {
  304.    if (pitch != au->pitch)
  305.       {
  306.       struct ext_message *msg;
  307.  
  308.       au->pitch = pitch;
  309.       msg = obtain_message();
  310.       msg->data.info.channel_mask = 1<<au->amiga_number;
  311.       msg->data.info.pitch = au->pitch;
  312.       msg->data.info.volume = au->volume;
  313.       send(msg, TYPE_CHANGE);
  314.       }
  315.    }
  316.  
  317. void set_play_volume(au, volume)
  318. struct audio_channel *au;
  319. int volume;
  320.    {
  321.    if (volume != au->volume)
  322.       {
  323.       struct ext_message *msg;
  324.  
  325.       au->volume = volume;
  326.       if (au->samp != empty_sample())
  327.          {
  328.          msg = obtain_message();
  329.          msg->data.info.channel_mask = 1<<au->amiga_number;
  330.          msg->data.info.pitch = au->pitch;
  331.          msg->data.info.volume = au->volume;
  332.          send(msg, TYPE_CHANGE);
  333.          }
  334.       }
  335.    }
  336.  
  337. void set_play_position(au, pos)
  338. struct audio_channel *au;
  339. int pos;
  340.    {
  341.    struct ext_message *msg, *msg2;
  342.    
  343.    
  344.    msg = obtain_message();
  345.    msg->data.info.channel_mask = 1<<au->amiga_number;
  346.    send(msg, TYPE_FLUSH_CHANNEL);
  347.  
  348.    if (au->samp->start)
  349.       {
  350.       if (pos < au->samp->length)
  351.          {
  352.          play_long_sample(au, au->samp->start + pos, au->samp->length - pos);
  353.          if (au->samp->rp_start)
  354.             {
  355.             msg = obtain_message();
  356.             msg2 = obtain_message();
  357.             msg->data.sample.start = au->samp->rp_start;
  358.             msg->data.sample.length = au->samp->rp_length;
  359.             msg2->data.info.channel_mask = 1<<au->amiga_number;
  360.             msg2->data.info.cycle = 0;
  361.             msg2->data.info.pitch = 0;
  362.             msg2->data.info.volume = 0;
  363.             Forbid();
  364.             send(msg, TYPE_SETUP);
  365.             send(msg2, TYPE_CHANGE);
  366.             Permit();
  367.             }  
  368.          }
  369.       }
  370.    }
  371.  
  372.  
  373.  
  374. void set_mix(percent)
  375. int percent;
  376.    {
  377.    }
  378.  
  379. int open_audio(f, s)
  380. int f, s;
  381.    {
  382.    ULONG freq;
  383.    LOCAL struct EClockVal dummy;
  384.  
  385.    INIT_ONCE;
  386.  
  387.       /* samples/sec used as a timing unit: 1sec =1 000 000 µs */
  388.    freq = ReadEClock(&dummy);
  389.    return (int)freq;
  390.    }
  391.    
  392. void set_synchro(s)
  393. int s;
  394.    {
  395.    }
  396.  
  397. int update_frequency()
  398.    {
  399.    return 0;
  400.    }
  401.  
  402. void flush_buffer(void)
  403.    {
  404.    }
  405.  
  406. void discard_buffer(void)
  407.    {
  408.    struct ext_message *msg;
  409.    
  410.    inhibit_output++;
  411.    msg = obtain_message();
  412.    send(msg, TYPE_FLUSH_BUFFER);
  413.    msg = obtain_message();
  414.    send(msg, TYPE_SYNC);
  415.    while (msg != await_type(TYPE_SYNC))
  416.       ;
  417.    inhibit_output--;
  418.    }
  419.  
  420.